﻿/*
 * array.c
 *
 *  Created on: 2019年5月5日
 *      Author: DELL
 */
#include <stdlib.h>
#include <string.h>
#include "array2.h"

/******************************************************************************************
 * @brief 	动态二维数组初始化
 * @param	array2:待添初始化二维数组指针
 * @param	row	  :动态数组的行
 * @param	column:动态数组的列
 * @retval	0:初始化成功    非0:初始化失败
 ******************************************************************************************/
Array2Err array2_malloc(Array2 *array2, uint16_t row, uint16_t column)
{
	if(array2 == NULL)
		return ARRAY2_PTR_ERR;

	if((row == 0) || (column == 0))
		return ARRAY2_SIZE_ERR;

	memset((uint8_t *)array2, 0, sizeof(Array2));
	array2->buffer = malloc(row * (column + 2));
	if(array2->buffer == NULL)						//如果内存不足，那么动态数组初始化失败
		return ARRAY2_MEM_ERR;

	memset(array2->buffer, 0, row * column);
	array2->row		= row;
	array2->column 	= column + 2;   //每行再增加两个字节用来存放一行的数据长度
	array2->read 	= 0;
	array2->write 	= 0;
	array2->full	= 0;

	return ARRAY2_OPS_OK;
}

/******************************************************************************************
 * @brief 	判断动态二维数组是否为空
 * @param	array2:待判断的二维数组指针
 * @retval	0:非空   1:空
 ******************************************************************************************/
int array2_is_empty(Array2 *array2)
{
	if(array2 == NULL)
		return 1;
	if((array2->read == array2->write) && (array2->full == 0))
		return 1;
	else
		return 0;
}

/******************************************************************************************
 * @brief 	判断动态二维数组是否为满
 * @param	array2:待判断的二维数组指针
 * @retval	0:非满   1:满
 ******************************************************************************************/
int array2_is_full(Array2 *array2)
{
	if(array2 == NULL)
		return 1;
	if(array2->full)
		return 1;
	else
		return 0;
}


/******************************************************************************************
 * @brief 	添加数据到动态二维数组最后一个取出的位置
 * @param	array2:待添加数据的二维数组指针
 * @param	buf	  :待添加数据
 * @param	size  :待添加数据大小
 * @retval	0:添加成功   非0:添加失败
 ******************************************************************************************/
Array2Err array2_put_lifo(Array2 *array2, uint8_t *buf, uint16_t size)
{
	uint8_t *ptr;

	if(array2 == NULL)
		return ARRAY2_PTR_ERR;
	if((size > array2->column) || (size == 0))
		return ARRAY2_SIZE_ERR;

	if(array2_is_full(array2))
		return ARRAY2_OPS_FULL;

	ptr = array2->buffer + array2->write * array2->column;
	*ptr = size & 0xff;						//前两个字节存放数据长度
	*(ptr + 1) = (size >> 8) & 0xff;
	memcpy(ptr + 2, buf, size);

	array2->write += 1;
	if(array2->write >= array2->row)
	{
		array2->write = 0;
	}

	if(array2->write == array2->read)
		array2->full = 1;

	return ARRAY2_OPS_OK;
}

/******************************************************************************************
 * @brief 	添加数据到动态二维数组最先取出的位置
 * @param	array2:待添加数据的二维数组指针
 * @param	buf	  :待添加数据
 * @param	size  :待添加数据大小
 * @retval	0:添加成功   非0:添加失败
 ******************************************************************************************/
Array2Err array2_put_fifo(Array2 *array2, uint8_t *buf, uint16_t size)
{
	uint8_t *ptr;

	if(array2 == NULL)
		return ARRAY2_PTR_ERR;

	if((size > array2->column) || (size == 0))
		return ARRAY2_SIZE_ERR;

	if(array2_is_full(array2))
		return ARRAY2_OPS_FULL;

	if(array2->read)
		array2->read -= 1;
	else
		array2->read = array2->row - 1;

	ptr = array2->buffer + array2->read * array2->column;
	*ptr = size & 0xff;						//前两个字节存放数据长度
	*(ptr + 1) = (size >> 8) & 0xff;
	memcpy(ptr + 2, buf, size);

	if(array2->write == array2->read)   //判断是否为满
		array2->full = 1;

	return ARRAY2_OPS_OK;
}

/******************************************************************************************
 * @brief 	读取动态二维数组的数据
 * @param	array2:待读取数据的二维数组指针
 * @param	buf	  :读取数据存放位置
 * @param	size  :数据读取大小
 * @retval	0:读取成功   非0:读取失败
 ******************************************************************************************/
Array2Err array2_post(Array2 *array2, uint8_t *buf, uint16_t *size)
{
	uint16_t len;
	uint8_t *ptr;

	if(array2 == NULL)
		return ARRAY2_PTR_ERR;

	if(array2_is_empty(array2))
		return ARRAY2_OPS_EMPTY;

	ptr = array2->buffer + array2->read * array2->column;
	len = *(ptr + 1);			//前两个字节存放数据长度
	len <<= 8;
	len |= *ptr;
	*size = len;
	memcpy(buf, ptr + 2, len);
	memset(ptr, 0, array2->column);		//读取完数据后，清空

	array2->read += 1;
	if(array2->read >= array2->row)
		array2->read = 0;

	if(array2->full == 1)
		array2->full = 0;

	return ARRAY2_OPS_OK;
}

/******************************************************************************************
 * @brief 	读取当前读指针指向的数据长度,不读取数据
 * @param	array2:待读取数据的二维数组指针
 * @retval	数据长度
 ******************************************************************************************/
uint16_t array2_get_size(Array2 *array2)
{
	uint16_t len;
	uint8_t *ptr;

	if(array2_is_empty(array2))
		return 0;

	ptr = array2->buffer + array2->read * array2->column;
	len = *(ptr + 1);			//前两个字节存放数据长度
	len <<= 8;
	len |= *ptr;

	return len;
}

/******************************************************************************************
 * @brief 	获取指定数组中整数数据的行数
 * @param	array2:待读取数据的二维数组指针
 * @retval	行数
 ******************************************************************************************/
uint16_t array2_get_row(Array2 *array2)
{
	if(array2 == NULL)
		return 0;

	if(array2_is_empty(array2))
		return 0;

	if(array2->read == array2->write)
	{
		return array2->row;
	}
	else
	{
		if(array2->read < array2->write)
		{
			return (array2->write - array2->read);
		}
		else
		{
			return (array2->write + array2->row - array2->read);
		}
	}
}

/******************************************************************************************
 * @brief 	释放数组
 * @param	array2:待释放的二维数组指针
 * @retval	操作结果
 ******************************************************************************************/
Array2Err array2_free(Array2 *array2)
{
	if(array2 == NULL)
		return ARRAY2_PTR_ERR;

	free(array2->buffer);
	array2->row		= 0;
	array2->column 	= 0;
	array2->read 	= 0;
	array2->write 	= 0;
	array2->full	= 0;

	return ARRAY2_OPS_OK;
}

/******************************************************************************************
 * @brief 	清空数组
 * @param	array2:待释放的二维数组指针
 * @retval	操作结果
 ******************************************************************************************/
Array2Err array2_clear(Array2 *array2)
{
	if(array2 == NULL)
		return ARRAY2_PTR_ERR;

	array2->read 	= 0;
	array2->write 	= 0;
	array2->full	= 0;

	return ARRAY2_OPS_OK;
}
